package cn.ahaoweb.drule.core.compile.provide;

import cn.ahaoweb.drule.core.compile.enums.ConditionFieldTypeEnum;
import cn.ahaoweb.drule.core.model.enums.NodeType;
import cn.ahaoweb.drule.core.model.info.TreeNode;
import lombok.Data;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Name: ObjectTree
 * @Description:
 * @Author: wangzhonghao
 * @Date: 2025/2/8 11:26
 */
@Data
public class ObjectTree implements Serializable {

    private List<Node> data;

    /**
     * 转换
     * @param treeNode
     */
    public ObjectTree(TreeNode treeNode){
        List<TreeNode> children = treeNode.getChildren();
        this.data = toNodes(children);
    }

    private static Node transform(TreeNode child) {
        Node node = new Node();
        node.setKind(child.getType());
        node.setType(ConditionFieldTypeEnum.Field);
        node.setContainsRuleObject(child.isRuleObject());
        node.setList(child.isList());
        node.setFieldName(child.getInfo().getName());
        node.setFieldCode(child.getInfo().getCode());
        node.setPath(child.getInfo().getPath());
        node.setDataType(child.getInfo().getFqcn());
        if (child.isRuleObject()){
            List<Node> children = toNodes(child.getChildren());
            node.setChildren(children);
        }
        return node;
    }

    private static List<Node> toNodes(List<TreeNode> children) {
        if (children == null || children.isEmpty()){
            return null;
        }
        return children.stream().map(ObjectTree::transform).collect(Collectors.toList());
    }

    @Data
    public static class Node implements Serializable{

        /**
         * 节点类型
         */
        private NodeType kind;

        /**
         * 字段类型
         */
        private ConditionFieldTypeEnum type;

        /**
         * 是否包含规则对象
         * 也就是类型为：{@link NodeType#RULE_OBJECT}, {@link NodeType#LIST_OF_RULE_OBJECT}
         */
        private Boolean containsRuleObject;

        /**
         * 是否是列表（集合）
         */
        private Boolean list;


        // 中文名称
        private String fieldName;

        // 编码(类名，字段名)
        private String fieldCode;

        // 路径（从root对象定位到该字段的路径）
        private String path;

        /**
         * 该字段类型的全限定名（还要包含泛型信息），等价于{@link Type#getTypeName()}
         */
        private String dataType;

        private List<Node> children;

    }

}
